package MF1DSolver;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import jmeshless.NewOkCancelDialog;

import nonequidistant.FEMShapeFunctions1D.FEMShapeFunction1D1Pow;
import nonequidistant.FEMSolver1D.FEMResult;
import nonequidistant.FEMSolver1D.StatMatrixGenerator;

import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import syntaxanalyser.PostfiksX;

import HashMatrix2.HashMatrix2;
import HashMatrix2.LUFactorization;
import Integration.GaussQuadrature;
import Integration.IFunction1D;
import MeshlessShapeFunctions.JGaussian;
import MeshlessShapeFunctions.JMeshlessInterpolationFunction1D;
import MeshlessShapeFunctions.JStKernel;
import MeshlessShapeFunctions.Particle;

public class AdaptiveScheme {

		MF1DSolver gen;

	    ArrayList<Particle> NodeList;
	    ArrayList<JMeshlessInterpolationFunction1D> FuncList;

	    String pString="1";
	    String wString="0";
	    String qString="10";
	    String fString="100";

	    IFunction1D p;
	    IFunction1D w;
	    IFunction1D q;
	    IFunction1D f;

	    double left;
	    double right;

	    boolean DirihetA;
	    double AVal;
	    boolean DirihetB;
	    double BVal;
	    
	    double h;
	    double rho;
	    int PolinomDegree;

	    public AdaptiveScheme(ArrayList<Particle> NodeList,double h,double rho, int PolinomDegree) {
	        this.NodeList = NodeList;
	        this.rho=rho;
	        this.h = h;
	        this.PolinomDegree = PolinomDegree;
	        generateCoefFuncs();
	        generateFunctions();

	    }

	    private void generateFunctions(){
	        FuncList = new ArrayList<JMeshlessInterpolationFunction1D>();
	        double xz = 0.0;
	        for (int i = 1; i < NodeList.size()-1; i++) {
	        	xz = Math.max(xz,NodeList.get(i).getX()-NodeList.get(i-1).getX());
	        }
	        	double tmpRho = 2.33*Math.max(0, NodeList.get(1).getX()-NodeList.get(0).getX());
	        	tmpRho = 1.5*xz;
	        	NodeList.get(0).setRho(tmpRho);
	        
        		JMeshlessInterpolationFunction1D tmp = new JMeshlessInterpolationFunction1D(PolinomDegree,NodeList.get(0).getX(),tmpRho,new JGaussian(tmpRho) ); 
        		tmp.setNodeList(NodeList);
            	FuncList.add(tmp );
	        for (int i = 1; i < NodeList.size()-1; i++) {
//	        	tmpRho = 2.33*Math.max(NodeList.get(i).getX()-NodeList.get(i-1).getX(), NodeList.get(i+1).getX()-NodeList.get(i).getX());
	        	NodeList.get(i).setRho(tmpRho);
	        	tmp = new JMeshlessInterpolationFunction1D(PolinomDegree,NodeList.get(i).getX(),tmpRho,new JGaussian(tmpRho) ); 
	        	tmp.setNodeList(NodeList);
	            FuncList.add(tmp );
	        }
//	        tmpRho = 2.33*Math.max(0, NodeList.get(NodeList.size()-1).getX()-NodeList.get(NodeList.size()-2).getX());
	        NodeList.get(NodeList.size()-1).setRho(tmpRho);
    		tmp = new JMeshlessInterpolationFunction1D(PolinomDegree,NodeList.get(NodeList.size()-1).getX(),tmpRho,new JGaussian(tmpRho) ); 
    		tmp.setNodeList(NodeList);
    		FuncList.add(tmp );
	    }

	    @SuppressWarnings("unused")
		private void generateCoefFuncs() {
//	        MatrixGenerator1 gen = new MatrixGenerator1(NodeList.get(0),NodeList.get(NodeList.size()-1));
	//
//	        gen.setLeft(left);
//	        gen.setRight(right);

	        p = new IFunction1D() {

	            public double calculate(double x) {
	                try {
	                    return PostfiksX.Calculate(pString, x);
	                } catch (Exception ex) {
	                    Logger.getLogger(AdaptiveScheme.class.getName()).log(Level.SEVERE, null, ex);
	                }
	                return 0;
	            }

	            public double calculateDerivaty(double x) {
	                throw new UnsupportedOperationException("Not supported yet.");
	            }
	        };
	        w = new IFunction1D() {

	            public double calculate(double x) {
	                try {
	                    return PostfiksX.Calculate(wString, x);
	                } catch (Exception ex) {
	                    Logger.getLogger(AdaptiveScheme.class.getName()).log(Level.SEVERE, null, ex);
	                }
	                return 0;
	            }

	            public double calculateDerivaty(double x) {
	                throw new UnsupportedOperationException("Not supported yet.");
	            }
	        };
	        q = new IFunction1D() {

	            public double calculate(double x) {
	                try {
	                    return PostfiksX.Calculate(qString, x);
	                } catch (Exception ex) {
	                    Logger.getLogger(AdaptiveScheme.class.getName()).log(Level.SEVERE, null, ex);
	                }
	                return 0;
	            }

	            public double calculateDerivaty(double x) {
	                throw new UnsupportedOperationException("Not supported yet.");
	            }
	        };
	        f = new IFunction1D() {

	            public double calculate(double x) {
	                try {
	                    return PostfiksX.Calculate(fString, x);
	                } catch (Exception ex) {
	                    Logger.getLogger(AdaptiveScheme.class.getName()).log(Level.SEVERE, null, ex);
	                }
	                return 0;
	            }

	            public double calculateDerivaty(double x) {
	                throw new UnsupportedOperationException("Not supported yet.");
	            }
	        };


	    }

	    private void generateMatrix(){
//	        MatrixGenerator1 gen = new MatrixGenerator1(NodeList.get(0),NodeList.get(NodeList.size()-1));
	        gen = new MF1DSolver();
	        gen.setLeft(left);
	        gen.setRight(right);
	        gen.setfString(fString);
	        gen.setwString(wString);
	        gen.setqString(qString);
	        gen.setpString(pString);
	        gen.setListOfShapeFunction(FuncList);
	        gen.setNodeList(NodeList);
	        gen.setAVal(AVal);
	        gen.setDirihetA(DirihetA);
	        gen.setBVal(BVal);
	        gen.setDirihetB(DirihetB);
	        gen.generate();

//	        gen.setLeft(left);
//	        gen.setRight(right);
	//
//	        for (int i = 0; i < b.length; i++) {
//	            //IFunction1D f1 = FuncList.get(i);
//	            gen.setF1(FuncList.get(i));
//	            gen.setF2(FuncList.get(i));
//	            //A.setValue(i, i, gen.getKe(p)+gen.getAdv(w)+gen.getMe(q));
//	            for (int j = 0; j < b.length; j++) {
//	                gen.setF2(FuncList.get(j));
//	                double val = gen.getKe(p)+gen.getAdv(w)+gen.getMe(q);
//	                A.setValue(i, j, val);
//	            }
//	            b[i] = gen.getFe(f);
//	        }

//	        System.out.println("\t==========================================");
//	        for (int i = 0; i < b.length; i++) {
//	            for (int j = 0; j < b.length; j++) {
//	                System.out.print(A.getValue(i, j)+"\t");
//	            }
//	            System.out.println("\t"+b[i]);
//	        }
//	        System.out.println("\t==========================================");
	    }

	    private double[] Solve(){	 
	    	this.generateMatrix();
	    	
	    	double[] res = gen.solvePenalty();
//	    	double[] resA = new double[res.length];
//	    	for (int i = 0; i < res.length; i++) {
//				ArrayList<Integer> pos = this.gen.A.getJRowIndex(i);
//				double tmp = 0.0;
//				for (Iterator<Integer> iterator = pos.iterator(); iterator.hasNext();) {
//					Integer position = iterator.next();
//					tmp+=res[position]*this.gen.A.getValue(i, position);
//				}
//				resA[i] = this.gen.b[i] - tmp;
//			}
//	    	
//	    	LUFactorization lu = new LUFactorization(this.gen.A);
//	    	resA = lu.calculate(resA);
//	    	
//	    	for (int i = 0; i < resA.length; i++) {
//				System.out.println(resA[i]);
//			}
//	    	System.out.println("======================================");
//	    	double x = 0.0;
//	    	XYSeries series1 = new XYSeries("error", true, true);
//	        while(x<=1.0001){
//	            double tmp = 0.0;
//	            for (int j = 0; j <FuncList.size(); j++) {
//	                tmp+= FuncList.get(j).calculate(x)*resA[j];
//	            }
////	            System.out.print(x+"\t"+tmp+"\n");
//	            series1.add(x,tmp);
//	            x+=0.002;
//	        }
//
//	        XYSeriesCollection col1 = new XYSeriesCollection(series1);
////	        col1.addSeries(series2);
//	        NewOkCancelDialog dialog1 = new NewOkCancelDialog(null, false, col1);
//	        dialog1.setLocationRelativeTo(null);
//	        dialog1.setVisible(true);
	    	
	    	
	        return res;
	    }

	    public void setAVal(double AVal) {
	        this.AVal = AVal;
	    }

	    public void setBVal(double BVal) {
	        this.BVal = BVal;
	    }

	    public void setDirihetA(boolean DirihetA) {
	        this.DirihetA = DirihetA;
	    }

	    public void setDirihetB(boolean DirihetB) {
	        this.DirihetB = DirihetB;
	    }

	    public void setfString(String fString) {
	        this.fString = fString;
	    }

	    public void setpString(String pString) {
	        this.pString = pString;
	    }

	    public void setqString(String qString) {
	        this.qString = qString;
	    }

	    public void setwString(String wString) {
	        this.wString = wString;
	    }

	    public void setLeft(double left) {
	        this.left = left;
	    }

	    public void setRight(double right) {
	        this.right = right;
	    }

	    private ArrayList<Double> generateMidPoints(){
	        ArrayList<Double> list = new ArrayList<Double>();
	        for (int i = 0; i < NodeList.size()-1; i++) {
	            list.add( ( NodeList.get(i).getX() + NodeList.get(i+1).getX() ) / 2.0);
	        }
	        return list;
	    }


	    public double[] adaptate(double O){
	        double[] res = null;
//	        this.generateCoefFuncs();
	        int NNNN = 0;
	        while(true){
	            this.generateFunctions();
	            XYSeriesCollection col = new XYSeriesCollection();
	            for (Iterator<JMeshlessInterpolationFunction1D> it = this.FuncList.iterator(); it.hasNext();) {
					JMeshlessInterpolationFunction1D jm = (JMeshlessInterpolationFunction1D) it.next();
					double x = 0.0;
					 	XYSeries series = new XYSeries("", true, true);
		    	        while(x<=1.0001){
		    	            double tmp = jm.calculate(x);
		    	            series.add(x,tmp);
		    	            x+=0.002;
		    	        }
		    	        col.addSeries(series);
				}
    	        NewOkCancelDialog dialog = new NewOkCancelDialog(null, false, col);
    	        dialog.setLocationRelativeTo(null);
    	        dialog.setVisible(true);
	            
	            this.generateMatrix();
	            res = this.Solve();
//	            System.out.println(NNNN+"\n=====================================================");
//	            System.out.println("f([");
                double x = 0;
                XYSeries series1 = new XYSeries("розвязок методом штрафу", true, true);
    	        XYSeries series2 = new XYSeries("розвязок аналітичний", true, true);
    	        while(x<=1.0001){
    	            double tmp = 0.0;
    	            for (int j = 0; j <FuncList.size(); j++) {
    	                tmp+= FuncList.get(j).calculate(x)*res[j];
    	            }
//    	            System.out.print(x+"\t"+tmp+"\n");
    	            series1.add(x,tmp);
    	            tmp = (1.0 / (Math.exp(100) - 1) * (1- Math.exp(100*x)) + x);
    	            series2.add(x,tmp);
    	            x+=0.002;
    	        }
//
    	        XYSeriesCollection col1 = new XYSeriesCollection(series1);
    	        col1.addSeries(series2);
    	        NewOkCancelDialog dialog1 = new NewOkCancelDialog(null, false, col1);
    	        dialog1.setLocationRelativeTo(null);
    	        dialog1.setVisible(true);

//	            for (int j = 0; j < b.length; j++) {
//	                System.out.println(NodeList.get(j)+"\t"+res[j]);
//	            }
//    	        System.out.println("])");
    	        System.out.println(NodeList.size());
	            System.out.println("============================================================================");

	            // перевірка умови нормал сітки...
	            MFResult femres = new MFResult(res, FuncList);

	            //1. обчислюєм похідну по середині відрізків-елементів.
	                ArrayList<Double> MidPoints = this.generateMidPoints();
	                ArrayList<Double> derivaties = new ArrayList<Double>();

	                for (int i = 0; i < MidPoints.size(); i++) {
	                    derivaties.add(femres.calculateDerivaty(MidPoints.get(i)));
	                }
	            //обчислюємо норму
	                ArrayList<Double> D = new ArrayList<Double>();
	                D.add(Math.abs(femres.calculate(MidPoints.get(0)) - femres.calculate(MidPoints.get(1))) / Math.abs( MidPoints.get(0) - MidPoints.get(1) ));
	                for (int i = 1; i < MidPoints.size()-1; i++) {
	                    double d1 = Math.abs(femres.calculate(MidPoints.get(i)) - femres.calculate(MidPoints.get(i-1))) / Math.abs( MidPoints.get(i) - MidPoints.get(i-1) );
	                    double d2 = Math.abs(femres.calculate(MidPoints.get(i)) - femres.calculate(MidPoints.get(i+1))) / Math.abs( MidPoints.get(i) - MidPoints.get(i+1) );
	                    D.add(Math.max(d1, d2));
	                }
	                D.add(Math.abs(femres.calculate(MidPoints.get( MidPoints.size()-1 )) - femres.calculate(MidPoints.get(MidPoints.size()-2))) / Math.abs( MidPoints.get(MidPoints.size()-1 ) - MidPoints.get(MidPoints.size()-2) ));

	            //обчислюємо Dhk
//	                double max = -1000000000000000.0;
//	                int pos = 0;
	                for (int k = 0; k < D.size(); k++) {
	                    Double d1 = D.get(k);
//	                    double hk = this.FuncList.get(k).gethLeft()+this.FuncList.get(k).gethRight();
	                    double hk = this.FuncList.get(k).getRho()*2;
//	                    hk=1.0;
	                    D.set(k, d1*hk);
//	                    if (max<D.get(k)) {
//	                        max = d1*hk;
//	                        pos = k;
//	                    }
//	                    System.out.println("============================================================================");
//	                    for (int j = 0; j < D.size(); j++) {
//	                        System.out.println(NodeList.get(j)+"\t"+D.get(j));
//	                    }
//	                    System.out.println("============================================================================");
	                }
	            // додаємо нові елементи
	                boolean key = false;
	                
//	                    if (D.get(pos)>O) {
//	                        key = true;
//	                        NodeList.add((NodeList.get(pos)+NodeList.get(pos+1)) / 2.0);
//	                    }

	                for (int i = 0; i < D.size(); i++) {
	                    Double d1 = D.get(i);
	                    if (d1>O) {
	                        key = true;
	                        NodeList.add(new Particle((NodeList.get(i).getX()+NodeList.get(i+1).getX()) / 2.0, 0, NodeList.size()));
	                    }
	                }
	                

	                if (key) {
	                	Particle[] tmp = new Particle[NodeList.size()];
	                    NodeList.toArray(tmp);
	                    Arrays.sort(tmp);
	                    
	                    NodeList = new ArrayList<Particle>();
	                    NodeList.addAll(Arrays.asList(tmp));
	                    for (int i = 0; i < NodeList.size(); i++) {
							NodeList.get(i).setNumber(i);
						}
	                    key = false;
	                    for (int i = 0; i < NodeList.size()-2; i++) {
//							System.out.println(NodeList.get(i+1).getX()-NodeList.get(i).getX());
	                    	double h1 = NodeList.get(i+1).getX()-NodeList.get(i).getX();
	                    	double h2 = NodeList.get(i+2).getX()-NodeList.get(i+1).getX();
	                    	if((h1>h2)&&(h1/h2>3)){
	                    		NodeList.add(new Particle((NodeList.get(i+1).getX()+NodeList.get(i).getX())/2, 0.0, 0));
	                    		key = true;
	                    	}else{
	                    		if(h2/h1>3){
	                    			NodeList.add(new Particle((NodeList.get(i+2).getX()+NodeList.get(i+1).getX())/2, 0.0, 0));
	                    			key = true;
	                    		}
	                    		
	                    	}
	                    	if (key) {
	    	                	tmp = new Particle[NodeList.size()];
	    	                    NodeList.toArray(tmp);
	    	                    Arrays.sort(tmp);
	    	                    
	    	                    NodeList = new ArrayList<Particle>();
	    	                    NodeList.addAll(Arrays.asList(tmp));
	    	                    for (int j = 0; j < NodeList.size(); j++) {
	    							NodeList.get(j).setNumber(j);
	    						}
	                    	}
//	                    	System.out.println("NodeList.add( new Particle(" + NodeList.get(i).getX()+" , 0,"+i+" ));");
						}
	                }else{
	                    break;
	                }
	                
	                
	                if(NNNN==5){break;}
	                NNNN++;


	            
	        }
	        
	        return res;

	    }

	    public double[] adaptate2(double O){
	        double[] res = null;
//	        this.generateCoefFuncs();
	        int NNNN = 0;
	        while(true){
	            this.generateFunctions();
	            XYSeriesCollection col = new XYSeriesCollection();
	            for (Iterator<JMeshlessInterpolationFunction1D> it = this.FuncList.iterator(); it.hasNext();) {
					JMeshlessInterpolationFunction1D jm = (JMeshlessInterpolationFunction1D) it.next();
					double x = 0.0;
					 	XYSeries series = new XYSeries("", true, true);
					 	System.out.println("x=[");
		    	        while(x<=1.0001){
		    	            double tmp = jm.calculate(x);
		    	            series.add(x,tmp);
		    	            System.out.print(x+"\t"+tmp+"\n");
		    	            x+=0.002;
		    	        }
		    	        col.addSeries(series);
		    	        System.out.println("];plot(x(:,1),x(:,2))");
				}
    	        NewOkCancelDialog dialog = new NewOkCancelDialog(null, false, col);
    	        dialog.setLocationRelativeTo(null);
    	        dialog.setVisible(true);
	            
//	            this.generateMatrix();
	            res = this.Solve();
//	            System.out.println(NNNN+"\n=====================================================");
//	            System.out.println("f([");
                double x = 0;
                XYSeries series1 = new XYSeries("розвязок методом штрафу", true, true);
    	        XYSeries series2 = new XYSeries("розвязок аналітичний", true, true);
    	        System.out.println("x=[");
    	        while(x<=1.0001){
    	            double tmp = 0.0;
    	            for (int j = 0; j <FuncList.size(); j++) {
    	                tmp+= FuncList.get(j).calculate(x)*res[j];
    	            }
    	            System.out.print(x+"\t"+tmp+"\n");
    	            series1.add(x,tmp);
    	            tmp = (1.0 / (Math.exp(100) - 1) * (1- Math.exp(100*x)) + x);
    	            
    	            series2.add(x,tmp);
    	            x+=0.002;
    	        }
    	        System.out.println("];plot(x(:,1),x(:,2))");
//
    	        XYSeriesCollection col1 = new XYSeriesCollection(series1);
    	        col1.addSeries(series2);
    	        NewOkCancelDialog dialog1 = new NewOkCancelDialog(null, false, col1);
    	        dialog1.setLocationRelativeTo(null);
    	        dialog1.setVisible(true);

//	            for (int j = 0; j < b.length; j++) {
//	                System.out.println(NodeList.get(j)+"\t"+res[j]);
//	            }
//    	        System.out.println("])");
    	        System.out.println(NodeList.size());
	            System.out.println("============================================================================");

	            // перевірка умови нормал сітки...
	            boolean key = false;
	            MFResult femres = new MFResult(res, FuncList);
	            
	            MFResult err = error(femres);
//	            FEMResult err = error2(femres);
	            
//	            ArrayList<Double> list = new ArrayList<Double>();
	            for (int i = 0; i < FuncList.size()-1; i++) {
	                double mid = ( (FuncList.get(i).getXii() + FuncList.get(i+1).getXii()) / 2.0);
	                double locErr = err.calculate(mid);
	                if (Math.abs(locErr)>O) {
						int num = (int) (Math.abs(locErr)/O);
						if(num==1){num++;}
						double locH =  (FuncList.get(i+1).getXii() - FuncList.get(i).getXii()) / num ;
						for (int j = 1; j < num; j++) {
							NodeList.add(new Particle(FuncList.get(i).getXii() + j*locH, 0.0, 0));
						}
						key = true;
					}
	            }
	            
	            
	            series1 = new XYSeries("Похибка", true, true);
	            x = 0.0;
    	        while(x<=1.0001){
//    	            System.out.print(x+"\t"+err.calculate(x)+"\n");
    	            series1.add(x,err.calculate(x));
    	            x+=0.002;
    	        }
//
    	        col1 = new XYSeriesCollection(series1);
    	        dialog1 = new NewOkCancelDialog(null, false, col1);
    	        dialog1.setLocationRelativeTo(null);
    	        dialog1.setVisible(true);
	            
	            
//	            // near boundaries  
//	            double[] errr = errorBoundaries(true, femres);
//	            double  error = 0.0;
//	        	for (int j = 0; j < errr.length; j++) {
//					error+=errr[j];
//				}
//	        	
//	        	error/=errr.length;
//	        	
//	        	if (error>O) {
//	                key = true;
//	                NodeList.add(new Particle((NodeList.get(0).getX()+NodeList.get(1).getX()) / 2.0, 0, 0));
//	                
//	            }
//	        	
//	        	errr = errorBoundaries(false, femres);
//	            error = 0.0;
//	        	for (int j = 0; j < errr.length; j++) {
//					error+=errr[j];
//				}
//	        	
//	        	error/=errr.length;
//	        	
//	        	if (error>O) {
//	                key = true;
//	                NodeList.add(new Particle((NodeList.get(res.length-1).getX()+NodeList.get(res.length-2).getX()) / 2.0, 0, 0));
//	            }
//	        	
//	            //inside
//	            for (int i = 1; i < res.length-2; i++) {
//	            	errr = errorInside(i, i+1, femres);
//	            	
//	            	error = 0.0;
//	            	for (int j = 0; j < errr.length; j++) {
//						error+=errr[j];
//					}
//	            	
//	            	error/=errr.length;
//	            	
//	            	if ((error>O)||(Double.isNaN(error))) {
//	                    key = true;
//	                    NodeList.add(new Particle((NodeList.get(i).getX()+NodeList.get(i+1).getX()) / 2.0, 0, 0));
//	                    if (Double.isNaN(error)) {
//							System.out.println("nan"+res.length);
//						}
//	                }
//				}
	                

	                if (key) {
	                	Particle[] tmp = new Particle[NodeList.size()];
	                    NodeList.toArray(tmp);
	                    Arrays.sort(tmp);
	                    
	                    NodeList = new ArrayList<Particle>();
	                    NodeList.addAll(Arrays.asList(tmp));
	                    for (int i = 0; i < NodeList.size(); i++) {
							NodeList.get(i).setNumber(i);
						}
	                    key = false;
	                    for (int i = 0; i < NodeList.size()-2; i++) {
//							System.out.println(NodeList.get(i+1).getX()-NodeList.get(i).getX());
	                    	double h1 = NodeList.get(i+1).getX()-NodeList.get(i).getX();
	                    	double h2 = NodeList.get(i+2).getX()-NodeList.get(i+1).getX();
	                    	if((h1>h2)&&(h1/h2>3)){
	                    		NodeList.add(new Particle((NodeList.get(i+1).getX()+NodeList.get(i).getX())/2, 0.0, 0));
	                    		key = true;
	                    	}else{
	                    		if(h2/h1>3){
	                    			NodeList.add(new Particle((NodeList.get(i+2).getX()+NodeList.get(i+1).getX())/2, 0.0, 0));
	                    			key = true;
	                    		}
	                    		
	                    	}
	                    	if (key) {
	    	                	tmp = new Particle[NodeList.size()];
	    	                    NodeList.toArray(tmp);
	    	                    Arrays.sort(tmp);
	    	                    
	    	                    NodeList = new ArrayList<Particle>();
	    	                    NodeList.addAll(Arrays.asList(tmp));
	    	                    for (int j = 0; j < NodeList.size(); j++) {
	    							NodeList.get(j).setNumber(j);
	    						}
	                    	}
//	                    	System.out.println("NodeList.add( new Particle(" + NodeList.get(i).getX()+" , 0,"+i+" ));");
						}
	                }else{
	                    break;
	                }
	                
	                
	                if(NNNN==5){break;}
	                NNNN++;


	            
	        }
	        
	        return res;

	    }
	    
	    public double[] errorInside(int i1,int i2, final MFResult femres) {
	    	int n = 5;
			double res[] = null;
			HashMatrix2 A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
			double[] b = new double[n];
			final JMeshlessInterpolationFunction1D f1 = FuncList.get(i1);
	        final JMeshlessInterpolationFunction1D f2 = FuncList.get(i2);
			ArrayList<FEMShapeFunction1D1Pow> FuncList = new ArrayList<FEMShapeFunction1D1Pow>();
			double h1 = (f2.getXii()-f1.getXii())/(double)n;
	        for (int i = 0; i < n; i++) {
	            FuncList.add(new FEMShapeFunction1D1Pow(f1.getXii()+h1*i, h1,h1));
	        }
	        
	        StatMatrixGenerator gen = new StatMatrixGenerator();
	        gen.setLeft(f1.getXii());
	        gen.setRight(f2.getXii());

	            gen.setF1(FuncList.get(0));
	            gen.setF2(FuncList.get(1));
	            double[][] tmp = null;
	            double[] tmpb = null;

	        for (int i = 0; i < b.length-1; i++) {
	            gen.setF1(FuncList.get(i));
	            gen.setF2(FuncList.get(i+1));
	            tmp = gen.getAll(p, q, w);
	            tmpb = gen.getFe(f);

	            A.setValue(i, i, A.getValue(i, i) + tmp[0][0]);
	            A.setValue(i, i+1, A.getValue(i, i+1) + tmp[0][1]);
	            A.setValue(i+1, i, A.getValue(i+1, i) + tmp[1][0]);
	            A.setValue(i+1, i+1, A.getValue(i+1, i+1) + tmp[1][1]);
	            b[i]+=tmpb[0];
	            b[i+1]+=tmpb[1];
	        }
	        
	        GaussQuadrature gau = new GaussQuadrature(10);
	        
	        
	        for (int i = 0; i < b.length; i++) {
	        	final FEMShapeFunction1D1Pow v = FuncList.get(i);
	        	IFunction1D fff = new IFunction1D() {
					
					@Override
					public double calculateDerivaty(double x) {
						// TODO Auto-generated method stub
						return 0;
					}
					
					@Override
					public double calculate(double x) {
						double uVal = femres.calculate(x);//f1.calculate(x)*u1+f2.calculate(x)*u2;
						double uDerVal = femres.calculateDerivaty(x);//f1.calculateDerivaty(x)*u1+f2.calculateDerivaty(x)*u2;
						return uDerVal*p.calculate(x)*v.calculateDerivaty(x) + uVal*w.calculate(x)*v.calculateDerivaty(x) + uVal*q.calculate(x)*v.calculate(x);
					}
				};
				
				double tmpxz = gau.justGauss(f1.getXii(), f2.getXii(), fff); 
				
				b[i] -= tmpxz;
				
				
				
			}
//			b[0]+= (f1.calculateDerivaty((f1.getXi()-f1.gethLeft()/2.0)) + f1.calculateDerivaty((f1.getXi()+f1.gethRight()/2.0)))*(u1)/2.0  - f1.calculateDerivaty((f1.getXi()+f1.gethRight()/2.0))*u1;
//			b[n-1]+= (f2.calculateDerivaty((f2.getXi()-f2.gethLeft()/2.0)) + f2.calculateDerivaty((f2.getXi()+f2.gethRight()/2.0)))*(u2)/2.0 - f2.calculateDerivaty((f2.getXi()+f2.gethRight()/2.0))*u2;
//			b[n-1] = 0.0;
//			A.setValue(n-1, n-2, 0.0);
			
			A.setValue(2, 1, 0.0);
			A.setValue(2, 2, 1.0);
			A.setValue(2, 3, 0.0);
			b[2] = 0.0;
			
	        LUFactorization lu = new LUFactorization(A);
	        res = lu.calculate(b);
//	        for (int i = 0; i < res.length; i++) {
//				System.out.println(res[i]);
//			}
			
			return res;
		}
	    
	    public double[] errorBoundaries(boolean isLeft, final MFResult femres) {
	    	int n = 5;
			double res[] = null;
			HashMatrix2 A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
			double[] b = new double[n];
			
			if (isLeft) {
				final JMeshlessInterpolationFunction1D f1 = FuncList.get(0);
		        final JMeshlessInterpolationFunction1D f2 = FuncList.get(1);
		        
		        ArrayList<FEMShapeFunction1D1Pow> FuncList = new ArrayList<FEMShapeFunction1D1Pow>();
				double h1 = (f2.getXii()-f1.getXii())/(double)n;
		        for (int i = 0; i < n; i++) {
		            FuncList.add(new FEMShapeFunction1D1Pow(f1.getXii()+h1*i, h1,h1));
		        }
		        
		        StatMatrixGenerator gen = new StatMatrixGenerator();
		        gen.setLeft(f1.getXii());
		        gen.setRight(f2.getXii());

		            gen.setF1(FuncList.get(0));
		            gen.setF2(FuncList.get(1));
		            double[][] tmp = null;
		            double[] tmpb = null;

		        for (int i = 0; i < b.length-1; i++) {
		            gen.setF1(FuncList.get(i));
		            gen.setF2(FuncList.get(i+1));
		            tmp = gen.getAll(p, q, w);
		            tmpb = gen.getFe(f);

		            A.setValue(i, i, A.getValue(i, i) + tmp[0][0]);
		            A.setValue(i, i+1, A.getValue(i, i+1) + tmp[0][1]);
		            A.setValue(i+1, i, A.getValue(i+1, i) + tmp[1][0]);
		            A.setValue(i+1, i+1, A.getValue(i+1, i+1) + tmp[1][1]);
		            b[i]+=tmpb[0];
		            b[i+1]+=tmpb[1];
		        }
		        
		        GaussQuadrature gau = new GaussQuadrature(10);
		        
		        
		        for (int i = 0; i < b.length; i++) {
		        	final FEMShapeFunction1D1Pow v = FuncList.get(i);
		        	IFunction1D fff = new IFunction1D() {
						
						@Override
						public double calculateDerivaty(double x) {
							// TODO Auto-generated method stub
							return 0;
						}
						
						@Override
						public double calculate(double x) {
							double uVal = femres.calculate(x);//f1.calculate(x)*u1+f2.calculate(x)*u2;
							double uDerVal = femres.calculateDerivaty(x);//f1.calculateDerivaty(x)*u1+f2.calculateDerivaty(x)*u2;
							return uDerVal*p.calculate(x)*v.calculateDerivaty(x) + uVal*w.calculate(x)*v.calculateDerivaty(x) + uVal*q.calculate(x)*v.calculate(x);
						}
					};
					
					double tmpxz = gau.justGauss(f1.getXii(), f2.getXii(), fff); 
					
					b[i] -= tmpxz;
				}
//				b[0]+= (f1.calculateDerivaty((f1.getXi()-f1.gethLeft()/2.0)) + f1.calculateDerivaty((f1.getXi()+f1.gethRight()/2.0)))*(u1)/2.0  - f1.calculateDerivaty((f1.getXi()+f1.gethRight()/2.0))*u1;
//				b[n-1]+= (f2.calculateDerivaty((f2.getXi()-f2.gethLeft()/2.0)) + f2.calculateDerivaty((f2.getXi()+f2.gethRight()/2.0)))*(u2)/2.0 - f2.calculateDerivaty((f2.getXi()+f2.gethRight()/2.0))*u2;
//				b[n-1] = 0.0;
//				A.setValue(n-1, n-2, 0.0);
				
				A.setValue(0, 0, 1.0);
				A.setValue(0, 1, 0.0);
				A.setValue(0, 2, 0.0);
				b[0] = 0.0;
				
		        LUFactorization lu = new LUFactorization(A);
		        res = lu.calculate(b);
//		        for (int i = 0; i < res.length; i++) {
//					System.out.println(res[i]);
//				}
		        
		        
			} else {
				final JMeshlessInterpolationFunction1D f1 = FuncList.get(FuncList.size()-2);
		        final JMeshlessInterpolationFunction1D f2 = FuncList.get(FuncList.size()-1);
		        
		        ArrayList<FEMShapeFunction1D1Pow> FuncList = new ArrayList<FEMShapeFunction1D1Pow>();
				double h1 = (f2.getXii()-f1.getXii())/(double)n;
		        for (int i = 0; i < n; i++) {
		            FuncList.add(new FEMShapeFunction1D1Pow(f1.getXii()+h1*i, h1,h1));
		        }
		        
		        StatMatrixGenerator gen = new StatMatrixGenerator();
		        gen.setLeft(f1.getXii());
		        gen.setRight(f2.getXii());

		            gen.setF1(FuncList.get(0));
		            gen.setF2(FuncList.get(1));
		            double[][] tmp = null;
		            double[] tmpb = null;

		        for (int i = 0; i < b.length-1; i++) {
		            gen.setF1(FuncList.get(i));
		            gen.setF2(FuncList.get(i+1));
		            tmp = gen.getAll(p, q, w);
		            tmpb = gen.getFe(f);

		            A.setValue(i, i, A.getValue(i, i) + tmp[0][0]);
		            A.setValue(i, i+1, A.getValue(i, i+1) + tmp[0][1]);
		            A.setValue(i+1, i, A.getValue(i+1, i) + tmp[1][0]);
		            A.setValue(i+1, i+1, A.getValue(i+1, i+1) + tmp[1][1]);
		            b[i]+=tmpb[0];
		            b[i+1]+=tmpb[1];
		        }
		        
		        GaussQuadrature gau = new GaussQuadrature(10);
		        
		        
		        for (int i = 0; i < b.length; i++) {
		        	final FEMShapeFunction1D1Pow v = FuncList.get(i);
		        	IFunction1D fff = new IFunction1D() {
						
						@Override
						public double calculateDerivaty(double x) {
							// TODO Auto-generated method stub
							return 0;
						}
						
						@Override
						public double calculate(double x) {
							double uVal = femres.calculate(x);//f1.calculate(x)*u1+f2.calculate(x)*u2;
							double uDerVal = femres.calculateDerivaty(x);//f1.calculateDerivaty(x)*u1+f2.calculateDerivaty(x)*u2;
							return uDerVal*p.calculate(x)*v.calculateDerivaty(x) + uVal*w.calculate(x)*v.calculateDerivaty(x) + uVal*q.calculate(x)*v.calculate(x);
						}
					};
					
					double tmpxz = gau.justGauss(f1.getXii(), f2.getXii(), fff); 
					
					b[i] -= tmpxz;
				}
//				b[0]+= (f1.calculateDerivaty((f1.getXi()-f1.gethLeft()/2.0)) + f1.calculateDerivaty((f1.getXi()+f1.gethRight()/2.0)))*(u1)/2.0  - f1.calculateDerivaty((f1.getXi()+f1.gethRight()/2.0))*u1;
//				b[n-1]+= (f2.calculateDerivaty((f2.getXi()-f2.gethLeft()/2.0)) + f2.calculateDerivaty((f2.getXi()+f2.gethRight()/2.0)))*(u2)/2.0 - f2.calculateDerivaty((f2.getXi()+f2.gethRight()/2.0))*u2;
//				b[n-1] = 0.0;
//				A.setValue(n-1, n-2, 0.0);
				
				A.setValue(n-1, n-1, 1.0);
				A.setValue(n-1, n-2, 0.0);
				A.setValue(n-1, n-3, 0.0);
				b[n-1] = 0.0;
				
		        LUFactorization lu = new LUFactorization(A);
		        res = lu.calculate(b);
//		        for (int i = 0; i < res.length; i++) {
//					System.out.println(res[i]);
//				}
			}
			
			
			
			return res;
		}
	    
	    public MFResult error(final MFResult femres) {
	    	ArrayList<JMeshlessInterpolationFunction1D> FuncList = new ArrayList<JMeshlessInterpolationFunction1D>();
//			double h1 = (this.right-this.left)/(double)(n-1);
	    	
//	    	double h1 = 0.01;
//	    	double h2 = this.FuncList.get(1).getXii() - this.FuncList.get(0).getXii();
//	    	h2/=2.0;
	    	
	    	ArrayList<Particle> pList = new ArrayList<Particle>();
	    	
	    	for (int i = 0; i < this.NodeList.size()-1; i++) {
	    		Particle particle = new Particle(this.NodeList.get(i).getX(), 0, pList.size());
	    		pList.add(particle);
	    		particle = new Particle(this.NodeList.get(i).getX() + (this.NodeList.get(i+1).getX() - this.NodeList.get(i).getX())/2.0, 0, pList.size());
	    		pList.add(particle);
			}
    		pList.add(new Particle(this.NodeList.get(NodeList.size()-1).getX(), 0, pList.size()));
	    	

	    		
	    		
    		FuncList = new ArrayList<JMeshlessInterpolationFunction1D>();
	        double xz = 0.0;
	        for (int i = 1; i < pList.size()-1; i++) {
	        	xz = Math.max(xz,pList.get(i).getX()-pList.get(i-1).getX());
	        }
//	        	double tmpRho = 2.33*Math.max(0, pList.get(1).getX()-pList.get(0).getX());
	        	double tmpRho = 2.33*xz;
	        	pList.get(0).setRho(tmpRho);
	        
        		JMeshlessInterpolationFunction1D tmp = new JMeshlessInterpolationFunction1D(PolinomDegree,pList.get(0).getX(),tmpRho,new JGaussian(tmpRho) ); 
        		tmp.setNodeList(pList);
            	FuncList.add(tmp );
	        for (int i = 1; i < pList.size()-1; i++) {
//	        	tmpRho = 2.33*Math.max(pList.get(i).getX()-pList.get(i-1).getX(), pList.get(i+1).getX()-pList.get(i).getX());
	        	pList.get(i).setRho(tmpRho);
	        	tmp = new JMeshlessInterpolationFunction1D(PolinomDegree,pList.get(i).getX(),tmpRho,new JGaussian(tmpRho) ); 
	        	tmp.setNodeList(pList);
	            FuncList.add(tmp );
	        }
//	        tmpRho = 2.33*Math.max(0, pList.get(pList.size()-1).getX()-pList.get(pList.size()-2).getX());
	        pList.get(pList.size()-1).setRho(tmpRho);
    		tmp = new JMeshlessInterpolationFunction1D(PolinomDegree,pList.get(pList.size()-1).getX(),tmpRho,new JGaussian(tmpRho) ); 
    		tmp.setNodeList(pList);
    		FuncList.add(tmp );
    		
    		
    		
	        int n = FuncList.size();
			double res[] = null;
			HashMatrix2 A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
			double[] b = new double[n];
			
	        
			gen = new MF1DSolver();
	        gen.setLeft(left);
	        gen.setRight(right);
	        gen.setfString(fString);
	        gen.setwString(wString);
	        gen.setqString(qString);
	        gen.setpString(pString);
	        gen.setListOfShapeFunction(FuncList);
	        gen.setNodeList(pList);
	        gen.setAVal(0.0);
	        gen.setDirihetA(DirihetA);
	        gen.setBVal(0.0);
	        gen.setDirihetB(DirihetB);
	        gen.generate();
	        
	        for (int i = 0; i < pList.size(); i++) {
	        	JMeshlessInterpolationFunction1D jm = FuncList.get(i);
                for (int j = 0; j < pList.size(); j++) {
                	double x = pList.get(j).getX();
                    A.setValue(j, i, jm.calculate(x));
                }
                b[i] = femres.calculate(pList.get(i).getX());
	        }
	        
	        LUFactorization lu = new LUFactorization(A);
	        double[] resU = lu.calculate(b);
	        
	        
	        double[] tmpU = new double[b.length];
			for (int j = 0; j < tmpU.length; j++) {
				ArrayList<Integer> pos = A.getJRowIndex(j);
				double tmpxz = 0.0;
//				double tmpxz2 = 0.0;
				for (int i = 0; i < pos.size(); i++) {
//					tmpxz += A.getValue(j, pos.get(i))*femres.calculate(FuncList.get(pos.get(i)).getXii());
					tmpxz += gen.A.getValue(j, pos.get(i))*resU[i];
				}
				gen.b[j]-=tmpxz;
			}

	        res = gen.solvePenalty();
			
			return new MFResult(res, FuncList);
		}
	    
	    public FEMResult error2(final MFResult femres) {
	    	ArrayList<FEMShapeFunction1D1Pow> FuncList = new ArrayList<FEMShapeFunction1D1Pow>();

	    	double h1 = 0.01;
	    	double h2 = this.FuncList.get(1).getXii() - this.FuncList.get(0).getXii();
	    	h2/=2.0;
	    	FuncList.add(new FEMShapeFunction1D1Pow(this.left, h1, h2));
	    	FuncList.add(new FEMShapeFunction1D1Pow(this.left + h2, h2, h2));
	    		
	    		
	        for (int i = 1; i < this.FuncList.size()-1; i++) {
	        	h1 = this.FuncList.get(i).getXii() - this.FuncList.get(i-1).getXii();
	        	h1/=2.0;
	        	h2 = this.FuncList.get(i+1).getXii() - this.FuncList.get(i).getXii();
	        	h2/=2.0;
	        	FuncList.add(new FEMShapeFunction1D1Pow(this.FuncList.get(i).getXii(), h1, h2));
	        	FuncList.add(new FEMShapeFunction1D1Pow(this.FuncList.get(i).getXii() + h2, h2, h2));
	        }
	        
	        h1 = this.FuncList.get(this.FuncList.size()-1).getXii() - this.FuncList.get(this.FuncList.size()-2).getXii();
	    	h1/=2.0;
	    	h2=0.001;
	    	FuncList.add(new FEMShapeFunction1D1Pow(this.FuncList.get(this.FuncList.size()-1).getXii(), h1, h2));
	        int n = FuncList.size();
			double res[] = null;
			HashMatrix2 A = new HashMatrix2(HashMatrix2.ARRAY_TYPE, n);
			double[] b = new double[n];
			
	        
	        StatMatrixGenerator gen = new StatMatrixGenerator();
	        gen.setLeft(left);
	        gen.setRight(right);

	            gen.setF1(FuncList.get(0));
	            gen.setF2(FuncList.get(1));
	            double[][] tmp = null;
	            double[] tmpb = null;

	        for (int i = 0; i < b.length-1; i++) {
	            gen.setF1(FuncList.get(i));
	            gen.setF2(FuncList.get(i+1));
	            tmp = gen.getAll(p, q, w);
	            tmpb = gen.getFe(f);

	            A.setValue(i, i, A.getValue(i, i) + tmp[0][0]);
	            A.setValue(i, i+1, A.getValue(i, i+1) + tmp[0][1]);
	            A.setValue(i+1, i, A.getValue(i+1, i) + tmp[1][0]);
	            A.setValue(i+1, i+1, A.getValue(i+1, i+1) + tmp[1][1]);
	            b[i]+=tmpb[0];
	            b[i+1]+=tmpb[1];
	        }

	        b[0] = 0.0;
	        A.setValue(0, 1, 0.0);
	        A.setValue(0, 0, 1.0);
			b[n-1] = 0.0;
			A.setValue(n-1, n-2, 0.0);
			A.setValue(n-1, n-1, 1.0);
	        
	        
	        double[] tmpU = new double[b.length];
			for (int j = 0; j < tmpU.length; j++) {
				ArrayList<Integer> pos = A.getJRowIndex(j);
				double tmpxz = 0.0;
				for (int i = 0; i < pos.size(); i++) {
					tmpxz += A.getValue(j, pos.get(i))*femres.calculate(FuncList.get(pos.get(i)).getXi());
				}
				b[j]-=tmpxz;
			}

	        LUFactorization lu = new LUFactorization(A);
	        res = lu.calculate(b);
			return new FEMResult(res, FuncList);
		}
	    

	    public static void main(String[] args){
	        ArrayList<Particle> NodeList = new ArrayList<Particle>();
	        double a = 0.0;
	        double b = 1.0;
	        int N = 10;
	        double h = (b-a)/N;
//	        for (int i = 0; i <= N; i++) {
//	        	NodeList.add(new Particle(a+h*i, 0, i));
//	        }
//	        NodeList.add( new Particle(0.0 , 0,0 ));
//			NodeList.add( new Particle(0.1 , 0,1 ));
//			NodeList.add( new Particle(0.2 , 0,2 ));
////			NodeList.add( new Particle(0.3 , 0,3 ));
////			NodeList.add( new Particle(0.4 , 0,4 ));
//			NodeList.add( new Particle(0.5 , 0,3 ));
////			NodeList.add( new Particle(0.6 , 0,6 ));
//			NodeList.add( new Particle(0.7 , 0,4 ));
////			NodeList.add( new Particle(0.75 , 0,8 ));
//			NodeList.add( new Particle(0.8 , 0,5 ));
////			NodeList.add( new Particle(0.85 , 0,10 ));
//			NodeList.add( new Particle(0.9, 0,6 ));
////			NodeList.add( new Particle(0.925 , 0,12 ));
//			NodeList.add( new Particle(0.95 , 0,7 ));
////			NodeList.add( new Particle(0.975 , 0,14 ));
//			NodeList.add( new Particle(1.0 , 0,8 ));
			
			
			
//	        NodeList.add( new Particle(0.0 , 0,0 ));
//			NodeList.add( new Particle(0.05 , 0,1 ));
//			NodeList.add( new Particle(0.1 , 0,2 ));
//			NodeList.add( new Particle(0.1125 , 0,3 ));
//			NodeList.add( new Particle(0.125 , 0,4 ));
//			NodeList.add( new Particle(0.1375 , 0,5 ));
//			NodeList.add( new Particle(0.15000000000000002 , 0,6 ));
//			NodeList.add( new Particle(0.16250000000000003 , 0,7 ));
//			NodeList.add( new Particle(0.17500000000000002 , 0,8 ));
//			NodeList.add( new Particle(0.1875 , 0,9 ));
//			NodeList.add( new Particle(0.2 , 0,10 ));
//			NodeList.add( new Particle(0.21250000000000002 , 0,11 ));
//			NodeList.add( new Particle(0.225 , 0,12 ));
//			NodeList.add( new Particle(0.2375 , 0,13 ));
//			NodeList.add( new Particle(0.25 , 0,14 ));
//			NodeList.add( new Particle(0.2625 , 0,15 ));
//			NodeList.add( new Particle(0.275 , 0,16 ));
//			NodeList.add( new Particle(0.28750000000000003 , 0,17 ));
//			NodeList.add( new Particle(0.30000000000000004 , 0,18 ));
//			NodeList.add( new Particle(0.31250000000000006 , 0,19 ));
//			NodeList.add( new Particle(0.32500000000000007 , 0,20 ));
//			NodeList.add( new Particle(0.3375 , 0,21 ));
//			NodeList.add( new Particle(0.35000000000000003 , 0,22 ));
//			NodeList.add( new Particle(0.36250000000000004 , 0,23 ));
//			NodeList.add( new Particle(0.375 , 0,24 ));
//			NodeList.add( new Particle(0.3875 , 0,25 ));
//			NodeList.add( new Particle(0.4 , 0,26 ));
//			NodeList.add( new Particle(0.41250000000000003 , 0,27 ));
//			NodeList.add( new Particle(0.42500000000000004 , 0,28 ));
//			NodeList.add( new Particle(0.4375 , 0,29 ));
//			NodeList.add( new Particle(0.45 , 0,30 ));
//			NodeList.add( new Particle(0.4625 , 0,31 ));
//			NodeList.add( new Particle(0.475 , 0,32 ));
//			NodeList.add( new Particle(0.4875 , 0,33 ));
//			NodeList.add( new Particle(0.5 , 0,34 ));
//			NodeList.add( new Particle(0.5125 , 0,35 ));
//			NodeList.add( new Particle(0.525 , 0,36 ));
//			NodeList.add( new Particle(0.5375000000000001 , 0,37 ));
//			NodeList.add( new Particle(0.55 , 0,38 ));
//			NodeList.add( new Particle(0.5625 , 0,39 ));
//			NodeList.add( new Particle(0.5750000000000001 , 0,40 ));
//			NodeList.add( new Particle(0.5875000000000001 , 0,41 ));
//			NodeList.add( new Particle(0.6000000000000001 , 0,42 ));
//			NodeList.add( new Particle(0.6125 , 0,43 ));
//			NodeList.add( new Particle(0.6250000000000001 , 0,44 ));
//			NodeList.add( new Particle(0.6375000000000002 , 0,45 ));
//			NodeList.add( new Particle(0.6500000000000001 , 0,46 ));
//			NodeList.add( new Particle(0.6625000000000001 , 0,47 ));
//			NodeList.add( new Particle(0.675 , 0,48 ));
//			NodeList.add( new Particle(0.7000000000000001 , 0,49 ));
//			NodeList.add( new Particle(0.7125000000000001 , 0,50 ));
//			NodeList.add( new Particle(0.7250000000000001 , 0,51 ));
//			NodeList.add( new Particle(0.7375 , 0,52 ));
//			NodeList.add( new Particle(0.75 , 0,53 ));
//			NodeList.add( new Particle(0.7625 , 0,54 ));
//			NodeList.add( new Particle(0.775 , 0,55 ));
//			NodeList.add( new Particle(0.8 , 0,56 ));
//			NodeList.add( new Particle(0.8125 , 0,57 ));
//			NodeList.add( new Particle(0.8250000000000001 , 0,58 ));
//			NodeList.add( new Particle(0.8375000000000001 , 0,59 ));
//			NodeList.add( new Particle(0.8500000000000001 , 0,60 ));
//			NodeList.add( new Particle(0.875 , 0,61 ));
//			NodeList.add( new Particle(0.8875 , 0,62 ));
//			NodeList.add( new Particle(0.9 , 0,63 ));
//			NodeList.add( new Particle(0.925 , 0,64 ));
//			NodeList.add( new Particle(0.95 , 0,65 ));
//			NodeList.add( new Particle(1.0 , 0,66 ));
	        
	        
	        double rho = 0.1*2.5;
	        NodeList.add(new Particle(0.0, rho,0));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.05, rho,1));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.1, rho,2));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.15000000000000002, rho,3));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.2, rho,4));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.25, rho,5));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.30000000000000004, rho,6));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.35000000000000003, rho,7));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.4, rho,8));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.45, rho,9));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.5, rho,10));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.55, rho,11));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.6000000000000001, rho,12));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.6500000000000001, rho,13));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.7000000000000001, rho,14));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.7250000000000001, rho,15));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.75, rho,16));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.775, rho,17));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.8, rho,18));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.8250000000000001, rho,19));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.8500000000000001, rho,20));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.875, rho,21));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.9, rho,22));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.925, rho,23));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.9375, rho,24));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.95, rho,25));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.9562499999999999, rho,26));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.9624999999999999, rho,27));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.96875, rho,28));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.975, rho,29));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.9875, rho,30));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(0.99375, rho,31));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	       NodeList.add(new Particle(1.0, rho,32));
	        NodeList.get(NodeList.size()-1).setRho(rho);
	        
	        
//	        NodeList.add(new Particle(0.0, rho,0));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.05, rho,1));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.1, rho,2));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.15000000000000002, rho,3));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.2, rho,4));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.25, rho,5));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.30000000000000004, rho,6));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.35000000000000003, rho,7));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.4, rho,8));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.45, rho,9));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.5, rho,10));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.55, rho,11));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.6000000000000001, rho,12));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.6500000000000001, rho,13));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.7000000000000001, rho,14));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.7250000000000001, rho,15));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.75, rho,16));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.775, rho,17));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.8, rho,18));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.8250000000000001, rho,19));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.8500000000000001, rho,20));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.875, rho,21));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.9, rho,22));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.925, rho,23));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.95, rho,24));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(0.975, rho,25));
//	        NodeList.get(NodeList.size()-1).setRho(rho);
//	       NodeList.add(new Particle(1.0, rho,26));
//	        NodeList.get(NodeList.size()-1).setRho(rho);

	        AdaptiveScheme gen = new AdaptiveScheme(NodeList,h, 1.33*h, 1);

	            gen.setLeft(a);
	            gen.setRight(b);
	            gen.setfString("0");
	            gen.setwString("100");
	            gen.setqString("0");
	            gen.setpString("1");
	            gen.setDirihetB(true);
	            gen.setBVal(1.0);
	            gen.setDirihetA(true);
	            gen.setAVal(0.0);

//	        gen.adaptate(1.091);
	            gen.adaptate2(0.01);
//	        gen.Solve();
	    }

	}
